package pjaws;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import pjaws.RootPawHandler.Status;

/**
 * 
 * @author Zachary Cancio
 * 
 * 
 */
public class Root extends Thread{

	private Vector<RootPawHandler> myPawHandlers;
	private Map<Integer, Status> myPawReceiveStatuses;
	private Map<Integer, Status> myPawSendStatuses;
	private String myHostname;
	private int myPort;

	//------CONSTRUCTORS------//
	public Root() {
		Initialize();
	}
	
	public void setHostnameAndPort(String hostname, int port){
		myHostname = hostname;
		myPort = port;
	}
	
	public String getHostname(){
		return myHostname;
	}
	
	public int getPort(){
		return myPort;
	}

	public Root(String filename) {
		Initialize();

		try {
			FileReader fr = new FileReader(filename);
			BufferedReader br = new BufferedReader(fr);
			String currLine;
			while ((currLine = br.readLine()) != null) {
				String[] values = currLine.split("\\s+");

				if (values[0].equals("PAW")) {
					int PawId = Integer.parseInt(values[1]);
					addPawReceiveStatus(PawId, RootPawHandler.Status.BUSY);
					addPawSendStatus(PawId, RootPawHandler.Status.BUSY);
				}
			}
			fr.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void Initialize() {
		myPawHandlers = new Vector<RootPawHandler>(10);
		myPawReceiveStatuses = new HashMap<Integer, RootPawHandler.Status>();
		myPawSendStatuses = new HashMap<Integer, RootPawHandler.Status>();
	}

	private void addPawHandler(RootPawHandler ph) {
		myPawHandlers.add(ph);
	}
	

	//----Receive Methods -----//
	public synchronized void addPawReceiveStatus(int PawId, Status s) {
		myPawReceiveStatuses.put(PawId, s);
	}

	public synchronized boolean areServersReadyToReceive() {
		int readyServers = 0;

		for (RootPawHandler.Status s : myPawReceiveStatuses.values()) {
			if (s == RootPawHandler.Status.READY) {
				readyServers++;
			}
		}

		return (myPawReceiveStatuses.size() == readyServers);
	}

	/** **Send Methods *** */
	public synchronized void addPawSendStatus(int PawId, Status s) {
		myPawSendStatuses.put(PawId, s);
	}

	public synchronized boolean areServersReadyToSend() {
		int readyServers = 0;

		for (RootPawHandler.Status s : myPawSendStatuses.values()) {
			if (s == RootPawHandler.Status.READY) {
				readyServers++;
			}
		}

		return (myPawSendStatuses.size() == readyServers);
	}

	public void run() {
		ServerSocket serverSocket = null;
		Socket socket = null;

		// accept paw connections
		try {
			serverSocket = new ServerSocket(PjawsConstants.ROOTPORT);
			System.out.println("ready to receive requests");
			while (true) {
				socket = serverSocket.accept();
				System.out.println("accepted request");
				RootPawHandler handler = new RootPawHandler(socket,
						myPawHandlers, this);
				addPawHandler(handler);
				handler.start();
			}
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			try {
				serverSocket.close();
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
	}

}
